package com.cdp.web.controller.system.report;

import com.cdp.common.core.domain.AjaxResult;
import com.cdp.system.dto.MakeReportDTO;
import com.cdp.system.dto.PerformanceFifthDTO;
import lombok.var;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.util.Units;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@RestController
@RequestMapping
public class TargetReportController {

    @Value("${filePython.upload-pkl-excel}")
    private String uploadPklExcelPath;

    @Value("${file.upload-dir}")
    private String fileUploadDir;

    /**
     * 目标性能预测报告
     *
     * @param makeReportDTO
     * @return
     */

    @PostMapping("/make/report/target/performance/first")
    public AjaxResult makeTargetReportFirst(@RequestBody MakeReportDTO makeReportDTO) {
        Map<String, String> textReplaceMap = new HashMap<>();

        // 替换日期
        LocalDateTime nowData = LocalDateTime.now();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        textReplaceMap.put("${nowDate}", nowData.format(dateFormatter));

        String templatePath = uploadPklExcelPath + "template1.docx";
        String directoryPath = fileUploadDir;

        try {
            if (!Files.exists(Paths.get(directoryPath))) {
                Files.createDirectories(Paths.get(directoryPath));
            }

            try (InputStream is = new FileInputStream(templatePath);
                 XWPFDocument doc = new XWPFDocument(is)) {

                // 替换普通文本占位符（段落和表格内文本）
                replaceTextPlaceholders(doc, textReplaceMap);

                List<List<String>> excelData = makeReportDTO.getExcelData();
                if (excelData == null || excelData.isEmpty()) {
                    return AjaxResult.error("excelData不能为空");
                }

                // 替换表格内容，按列替换，且新增行
                replaceTableDataByColumns(doc, excelData);

                // 生成唯一文件名
                String fileName = generateUniqueFileName();
                String outPath = directoryPath + fileName;

                try (OutputStream os = new FileOutputStream(outPath)) {
                    doc.write(os);
                }

                return AjaxResult.success(outPath);
            }
        } catch (FileNotFoundException e) {
            return AjaxResult.error("文件未找到：" + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("报告生成失败：" + e.getMessage());
        }
    }

    private void replaceTextPlaceholders(XWPFDocument doc, Map<String, String> replaceMap) {
        // 替换段落中的占位符
        doc.getParagraphs().forEach(paragraph -> {
            paragraph.getRuns().forEach(run -> {
                String text = run.getText(0);
                if (text != null) {
                    for (Map.Entry<String, String> entry : replaceMap.entrySet()) {
                        if (text.contains(entry.getKey())) {
                            run.setText(text.replace(entry.getKey(), entry.getValue()), 0);
                        }
                    }
                }
            });
        });

        // 替换表格中的占位符
        doc.getTables().forEach(table -> {
            table.getRows().forEach(row -> {
                row.getTableCells().forEach(cell -> {
                    cell.getParagraphs().forEach(paragraph -> {
                        paragraph.getRuns().forEach(run -> {
                            String text = run.getText(0);
                            if (text != null) {
                                for (Map.Entry<String, String> entry : replaceMap.entrySet()) {
                                    if (text.contains(entry.getKey())) {
                                        run.setText(text.replace(entry.getKey(), entry.getValue()), 0);
                                    }
                                }
                            }
                        });
                    });
                });
            });
        });
    }


    private void replaceTableDataByColumns(XWPFDocument doc, List<List<String>> excelData) {
        if (doc.getTables().isEmpty()) {
            throw new IllegalArgumentException("模板中没有表格");
        }

        XWPFTable table = doc.getTables().get(0);

        // 确保数据至少有5列，如果不足则补充空列
        while (excelData.size() < 6) {
            excelData.add(new ArrayList<>());
        }


        // 求最大行数
        int maxRowCount = excelData.stream()
                .mapToInt(List::size)
                .max()
                .orElse(0);

        int templateRowCount = table.getNumberOfRows();

        // 不够行就新增
        for (int i = templateRowCount; i < maxRowCount; i++) {
            table.createRow();
        }

        for (int col = 0; col < excelData.size(); col++) {
            List<String> colData = excelData.get(col);

            for (int row = 0; row < maxRowCount; row++) {
                XWPFTableRow tableRow = table.getRow(row);

                // 设置固定高度为 5mm（约 284 Twips）
                tableRow.setHeight(284);
                tableRow.setHeightRule(TableRowHeightRule.EXACT);

                // 确保当前行有对应列单元格
                while (tableRow.getTableCells().size() <= col) {
                    tableRow.createCell();
                }

                XWPFTableCell cell = tableRow.getCell(col);

                // 清空旧内容
                cell.removeParagraph(0);

                // 写入新文本并设置字体样式为小四宋体（12pt）
                XWPFParagraph paragraph = cell.addParagraph();
                XWPFRun run = paragraph.createRun();

                // 处理空值情况，用"/"填充
                String text = row < colData.size() ? colData.get(row) : "";
                if (text == null || text.trim().isEmpty()) {
                    text = "/";
                }

                run.setText(text);
                run.setFontFamily("宋体");
                run.setFontSize(10); // 小四：12pt
            }
        }
    }

    /**
     * 生成唯一文件名
     */
    private String generateUniqueFileName() {
        long timestamp = System.currentTimeMillis();
        int randomNum = new Random().nextInt(10000);
        return timestamp + "_" + randomNum + ".docx";
    }


/*666
    @PostMapping("/make/report/target/performance/first")
    public AjaxResult makeTargetReportFirst(@RequestBody MakeReportDTO makeReportDTO) {
        Map<String, String> textReplaceMap = new HashMap<>();

        // 替换日期
        LocalDateTime nowData = LocalDateTime.now();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        textReplaceMap.put("${nowDate}", nowData.format(dateFormatter));

        String templatePath = uploadPklExcelPath + "template1.docx";
        String directoryPath = fileUploadDir;

        try {
            if (!Files.exists(Paths.get(directoryPath))) {
                Files.createDirectories(Paths.get(directoryPath));
            }

            try (InputStream is = new FileInputStream(templatePath);
                 XWPFDocument doc = new XWPFDocument(is)) {

                // 替换普通文本占位符（段落和表格内文本）
                replaceTextPlaceholders(doc, textReplaceMap);

                List<List<String>> excelData = makeReportDTO.getExcelData();
                if (excelData == null || excelData.isEmpty()) {
                    return AjaxResult.error("excelData不能为空");
                }

                // 替换表格内容，按列替换，且新增行
                replaceTableDataByColumns(doc, excelData);

                // 生成唯一文件名
                String fileName = generateUniqueFileName();
                String outPath = directoryPath + fileName;

                try (OutputStream os = new FileOutputStream(outPath)) {
                    doc.write(os);
                }

                return AjaxResult.success(outPath);
            }
        } catch (FileNotFoundException e) {
            return AjaxResult.error("文件未找到：" + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("报告生成失败：" + e.getMessage());
        }
    }

    private void replaceTextPlaceholders(XWPFDocument doc, Map<String, String> replaceMap) {
        // 替换段落中的占位符
        doc.getParagraphs().forEach(paragraph -> {
            paragraph.getRuns().forEach(run -> {
                String text = run.getText(0);
                if (text != null) {
                    for (Map.Entry<String, String> entry : replaceMap.entrySet()) {
                        if (text.contains(entry.getKey())) {
                            run.setText(text.replace(entry.getKey(), entry.getValue()), 0);
                        }
                    }
                }
            });
        });

        // 替换表格中的占位符
        doc.getTables().forEach(table -> {
            table.getRows().forEach(row -> {
                row.getTableCells().forEach(cell -> {
                    cell.getParagraphs().forEach(paragraph -> {
                        paragraph.getRuns().forEach(run -> {
                            String text = run.getText(0);
                            if (text != null) {
                                for (Map.Entry<String, String> entry : replaceMap.entrySet()) {
                                    if (text.contains(entry.getKey())) {
                                        run.setText(text.replace(entry.getKey(), entry.getValue()), 0);
                                    }
                                }
                            }
                        });
                    });
                });
            });
        });
    }



    private void replaceTableDataByColumns(XWPFDocument doc, List<List<String>> excelData) {
        if (doc.getTables().isEmpty()) {
            throw new IllegalArgumentException("模板中没有表格");
        }

        XWPFTable table = doc.getTables().get(0);

        // 求最大行数
        int maxRowCount = excelData.stream()
                .mapToInt(List::size)
                .max()
                .orElse(0);

        int templateRowCount = table.getNumberOfRows();

        // 不够行就新增
        for (int i = templateRowCount; i < maxRowCount; i++) {
            table.createRow();
        }

        for (int col = 0; col < excelData.size(); col++) {
            List<String> colData = excelData.get(col);

            for (int row = 0; row < maxRowCount; row++) {
                XWPFTableRow tableRow = table.getRow(row);

                // 设置固定高度为 5mm（约 284 Twips）
                tableRow.setHeight(284);
                tableRow.setHeightRule(TableRowHeightRule.EXACT);

                // 确保当前行有对应列单元格
                while (tableRow.getTableCells().size() <= col) {
                    tableRow.createCell();
                }

                XWPFTableCell cell = tableRow.getCell(col);

                // 清空旧内容
                cell.removeParagraph(0);

                // 写入新文本并设置字体样式为小四宋体（12pt）
                XWPFParagraph paragraph = cell.addParagraph();
                XWPFRun run = paragraph.createRun();
                String text = row < colData.size() ? colData.get(row) : "";
                run.setText(text);
                run.setFontFamily("宋体");
                run.setFontSize(10); // 小四：12pt
            }
        }
    }

    private String generateUniqueFileName() {
        long timestamp = System.currentTimeMillis();
        int randomNum = new Random().nextInt(10000);
        return timestamp + "_" + randomNum + ".docx";
    }

*/


    /*
     */

    /**
     * 目标性能预测报告
     *
     * @param makeReportDTO
     * @return
     */

    @PostMapping("make/report/target/performance/second")
    public AjaxResult makeTargetReportFirstSecond(@RequestBody MakeReportDTO makeReportDTO) {
        Map<String, String> textReplaceMap = new HashMap<>();

        // 替换日期
        LocalDateTime nowData = LocalDateTime.now();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        textReplaceMap.put("${nowDate}", nowData.format(dateFormatter));

        String templatePath = uploadPklExcelPath + "template2.docx";
        String directoryPath = fileUploadDir;

        try {
            if (!Files.exists(Paths.get(directoryPath))) {
                Files.createDirectories(Paths.get(directoryPath));
            }

            try (InputStream is = new FileInputStream(templatePath);
                 XWPFDocument doc = new XWPFDocument(is)) {

                // 替换普通文本占位符（段落和表格内文本）
                replaceTextPlaceholders(doc, textReplaceMap);

                List<List<String>> excelData = makeReportDTO.getExcelData();
                if (excelData == null || excelData.isEmpty()) {
                    return AjaxResult.error("excelData不能为空");
                }
                // 当数据组数超过6时，删除超出部分
                if (excelData.size() > 6) {
                    // 截取前6条数据
                    excelData = excelData.subList(0, 6);
                    // 如果需要保留原引用，可以清空后添加
                    // excelData.clear();
                    // excelData.addAll(tempList);
                }
                // 替换表格内容，按列替换，且新增行
                replaceTableDataByColumns(doc, excelData);

                // 生成唯一文件名
                String fileName = generateUniqueFileName();
                String outPath = directoryPath + fileName;

                try (OutputStream os = new FileOutputStream(outPath)) {
                    doc.write(os);
                }

                return AjaxResult.success(outPath);
            }
        } catch (FileNotFoundException e) {
            return AjaxResult.error("文件未找到：" + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("报告生成失败：" + e.getMessage());
        }
    }


    /**
     * 导出excel
     */
    @PostMapping("exportExcel")
    public void exportExcel(@RequestBody MakeReportDTO makeReportDTO, HttpServletResponse response) {
        List<List<String>> excelData = makeReportDTO.getExcelData();

        // 数据验证
        if (excelData == null || excelData.isEmpty()) {
            try {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST, "excelData不能为空");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;
        }



        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName;
        try {
            fileName = URLEncoder.encode("混凝土配合比数据.xlsx", "UTF-8");
        } catch (Exception e) {
            fileName = "concrete_data.xlsx";
            e.printStackTrace();
        }
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

        try (Workbook workbook = new XSSFWorkbook();
             var outputStream = response.getOutputStream()) {

            // 创建工作表
            Sheet sheet = workbook.createSheet("力学性能数据");

            // 创建样式 - 表头样式（居中对齐）
            CellStyle headerStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);
            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            headerStyle.setBorderBottom(BorderStyle.THIN);
            headerStyle.setBorderLeft(BorderStyle.THIN);
            headerStyle.setBorderRight(BorderStyle.THIN);
            headerStyle.setBorderTop(BorderStyle.THIN);
            headerStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中
            headerStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中

            // 创建样式 - 数据样式（居中对齐）
            CellStyle dataStyle = workbook.createCellStyle();
            dataStyle.setBorderBottom(BorderStyle.THIN);
            dataStyle.setBorderLeft(BorderStyle.THIN);
            dataStyle.setBorderRight(BorderStyle.THIN);
            dataStyle.setBorderTop(BorderStyle.THIN);
            dataStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中
            dataStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中

            // 写入数据
            for (int rowIndex = 0; rowIndex < excelData.size(); rowIndex++) {
                Row row = sheet.createRow(rowIndex);
                List<String> rowData = excelData.get(rowIndex);

                for (int cellIndex = 0; cellIndex < rowData.size(); cellIndex++) {
                    Cell cell = row.createCell(cellIndex);
                    cell.setCellValue(rowData.get(cellIndex));

                    // 设置样式
                    if (rowIndex == 0) {
                        cell.setCellStyle(headerStyle);
                    } else {
                        cell.setCellStyle(dataStyle);
                    }
                }
            }

            // 设置列间隔（宽度）为5个字符宽度
            for (int i = 0; i < excelData.get(0).size(); i++) {
                sheet.setColumnWidth(i, 10 * 256); // 256是POI中字符宽度单位
            }

            // 写入输出流
            workbook.write(outputStream);

        } catch (IOException e) {
            e.printStackTrace();
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "导出Excel失败");
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }


    /**
     * 替换表格数据，按列替换，且新增行
     *
     * @param doc       文档对象
     * @param excelData 表格数据
     */
    private void replaceTableDataByColumnsC(XWPFDocument doc, List<List<String>> excelData) {
        // 获取文档中的所有表格
        List<XWPFTable> tables = doc.getTables();
        if (tables == null || tables.isEmpty()) {
            return;
        }

        // 假设我们要替换第一个表格
        XWPFTable table = tables.get(0);

        // 获取表格的行数和列数
        int rowCount = table.getRows().size();
        int colCount = excelData.get(0).size();

        // 确保表格有足够的行来容纳数据
        for (int i = rowCount; i < excelData.size(); i++) {
            table.createRow();
        }

        // 填充表格数据
        for (int rowIndex = 0; rowIndex < excelData.size(); rowIndex++) {
            XWPFTableRow row = table.getRow(rowIndex);
            List<String> rowData = excelData.get(rowIndex);

            // 确保行中有足够的单元格
            while (row.getTableCells().size() < colCount) {
                row.addNewTableCell();
            }

            // 填充单元格数据
            for (int colIndex = 0; colIndex < colCount; colIndex++) {
                XWPFTableCell cell = row.getCell(colIndex);

                // 处理空值情况，用"/"填充
                String cellValue = rowData.size() > colIndex ? rowData.get(colIndex) : "";
                if (cellValue == null || cellValue.trim().isEmpty()) {
                    cellValue = "/";
                }

                // 清除单元格内容并设置新值
                cell.removeParagraph(0);
                XWPFParagraph paragraph = cell.addParagraph();
                XWPFRun run = paragraph.createRun();
                run.setText(cellValue);
            }
        }
    }


    /**
     * 目标性能预测报告
     *
     * @param makeReportDTO
     * @return
     */
    @PostMapping("make/report/target/performance/third")
    public AjaxResult makeTargetReportFirstThird(@RequestBody MakeReportDTO makeReportDTO) {
        Map<String, String> textReplaceMap = new HashMap<>();

        // 替换日期
        LocalDateTime nowData = LocalDateTime.now();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        textReplaceMap.put("${nowDate}", nowData.format(dateFormatter));

        String templatePath = uploadPklExcelPath + "template2.docx";
        String directoryPath = fileUploadDir;

        try {
            if (!Files.exists(Paths.get(directoryPath))) {
                Files.createDirectories(Paths.get(directoryPath));
            }

            try (InputStream is = new FileInputStream(templatePath);
                 XWPFDocument doc = new XWPFDocument(is)) {

                // 替换普通文本占位符（段落和表格内文本）
                replaceTextPlaceholders(doc, textReplaceMap);

                List<List<String>> excelData = makeReportDTO.getExcelData();
                if (excelData == null || excelData.isEmpty()) {
                    return AjaxResult.error("excelData不能为空");
                }

                // 替换表格内容，按列替换，且新增行
                replaceTableDataByColumns(doc, excelData);

                // 生成唯一文件名
                String fileName = generateUniqueFileName();
                String outPath = directoryPath + fileName;

                try (OutputStream os = new FileOutputStream(outPath)) {
                    doc.write(os);
                }

                return AjaxResult.success(outPath);
            }
        } catch (FileNotFoundException e) {
            return AjaxResult.error("文件未找到：" + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("报告生成失败：" + e.getMessage());
        }
    }




 /*   public AjaxResult makeTargetReportThird(@RequestBody MakeReportDTO makeReportDTO) {
        // 文本占位符
        Map<String, String> textReplaceMap = new HashMap<>();

        // 获取当前日期
        LocalDateTime nowData = LocalDateTime.now();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        String dateStr = nowData.format(dateFormatter);
        textReplaceMap.put("${nowDate}", dateStr); // 当前日期替换

        // 填充其他数据
        List<List<String>> excelData = makeReportDTO.getExcelData();
        textReplaceMap.put("${1}", excelData.get(0).get(0)); // 示例：水的数值替换
        textReplaceMap.put("${2}", excelData.get(0).get(1)); // 水泥PⅡ 52.5R
        textReplaceMap.put("${3}", excelData.get(0).get(2)); // 机制砂
        textReplaceMap.put("${5}", excelData.get(0).get(4)); // 碎石
        textReplaceMap.put("${6}", excelData.get(0).get(5)); // 矿渣粉
        textReplaceMap.put("${7}", excelData.get(0).get(6)); // 粉煤灰
        textReplaceMap.put("${8}", excelData.get(0).get(7)); // 减水剂
        textReplaceMap.put("${9}", excelData.get(0).get(8)); // 增效剂
        textReplaceMap.put("${10}", excelData.get(0).get(9)); // 3天抗压强度
        textReplaceMap.put("${11}", excelData.get(0).get(10)); // 7天抗压强度
        textReplaceMap.put("${12}", excelData.get(0).get(11)); // 28天抗压强度

        // Excel 文件路径和模板路径
        String templatePath = uploadPklExcelPath + "template3.docx";
        String directoryPath = fileUploadDir;

        try {
            // 检查目录并创建目录
            if (!Files.exists(Paths.get(directoryPath))) {
                Files.createDirectories(Paths.get(directoryPath));
            }

            // 创建和替换报告内容
            try (InputStream is = new FileInputStream(templatePath);
                 XWPFDocument doc = new XWPFDocument(is)) {

                // 替换段落
                for (XWPFParagraph paragraph : doc.getParagraphs()) {
                    replaceInParagraph(paragraph, textReplaceMap);
                }

                // 替换表格
                for (XWPFTable table : doc.getTables()) {
                    for (XWPFTableRow row : table.getRows()) {
                        for (XWPFTableCell cell : row.getTableCells()) {
                            for (XWPFParagraph paragraph : cell.getParagraphs()) {
                                replaceInParagraph(paragraph, textReplaceMap);
                            }
                        }
                    }

                    // 填充表格内容，自动填充多行
                    fillTableData(table, makeReportDTO.getExcelData());
                }

                long timestamp = System.currentTimeMillis();
                int randomNum = new Random().nextInt(10000);
                String fileName = timestamp + "_" + randomNum + ".docx";
                String outPath = directoryPath + fileName;

                // 输出到文件
                try (OutputStream os = new FileOutputStream(outPath)) {
                    doc.write(os);
                }

                return AjaxResult.success(outPath);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("报告生成失败！");
        }
    }
*/

    /**
     * 目标性能预测报告
     *
     * @param makeReportDTO
     * @return
     */
    @PostMapping("make/report/target/performance/fourth")
    public AjaxResult makeTargetReportFirstFourth(@RequestBody MakeReportDTO makeReportDTO) {
        Map<String, String> textReplaceMap = new HashMap<>();

        // 替换日期
        LocalDateTime nowData = LocalDateTime.now();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        textReplaceMap.put("${nowDate}", nowData.format(dateFormatter));

        String templatePath = uploadPklExcelPath + "template4.docx";
        String directoryPath = fileUploadDir;

        try {
            if (!Files.exists(Paths.get(directoryPath))) {
                Files.createDirectories(Paths.get(directoryPath));
            }

            try (InputStream is = new FileInputStream(templatePath);
                 XWPFDocument doc = new XWPFDocument(is)) {

                // 替换普通文本占位符（段落和表格内文本）
                replaceTextPlaceholders(doc, textReplaceMap);

                List<List<String>> excelData = makeReportDTO.getExcelData();
                if (excelData == null || excelData.isEmpty()) {
                    return AjaxResult.error("excelData不能为空");
                }

                // 替换表格内容，按列替换，且新增行
                replaceTableDataByColumns(doc, excelData);

                // 生成唯一文件名
                String fileName = generateUniqueFileName();
                String outPath = directoryPath + fileName;

                try (OutputStream os = new FileOutputStream(outPath)) {
                    doc.write(os);
                }

                return AjaxResult.success(outPath);
            }
        } catch (FileNotFoundException e) {
            return AjaxResult.error("文件未找到：" + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("报告生成失败：" + e.getMessage());
        }
    }

/*
    public AjaxResult makeTargetReportFourth(@RequestBody MakeReportDTO makeReportDTO) {
        // 文本占位符
        Map<String, String> textReplaceMap = new HashMap<>();

        // 获取当前日期
        LocalDateTime nowData = LocalDateTime.now();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        String dateStr = nowData.format(dateFormatter);
        textReplaceMap.put("${nowDate}", dateStr); // 当前日期替换

        // 填充其他数据
        List<List<String>> excelData = makeReportDTO.getExcelData();
        textReplaceMap.put("${1}", excelData.get(0).get(0)); // 示例：水的数值替换
        textReplaceMap.put("${2}", excelData.get(0).get(1)); // 水泥PⅡ 52.5R
        textReplaceMap.put("${3}", excelData.get(0).get(2)); // 机制砂
        textReplaceMap.put("${5}", excelData.get(0).get(4)); // 碎石
        textReplaceMap.put("${6}", excelData.get(0).get(5)); // 矿渣粉
        textReplaceMap.put("${7}", excelData.get(0).get(6)); // 粉煤灰
        textReplaceMap.put("${8}", excelData.get(0).get(7)); // 减水剂
        textReplaceMap.put("${9}", excelData.get(0).get(8)); // 增效剂
        textReplaceMap.put("${10}", excelData.get(0).get(9)); // 3天抗压强度
        textReplaceMap.put("${11}", excelData.get(0).get(10)); // 7天抗压强度
        textReplaceMap.put("${12}", excelData.get(0).get(11)); // 28天抗压强度

        // Excel 文件路径和模板路径
        String templatePath = uploadPklExcelPath + "template4.docx";
        String directoryPath = fileUploadDir;

        try {
            // 检查目录并创建目录
            if (!Files.exists(Paths.get(directoryPath))) {
                Files.createDirectories(Paths.get(directoryPath));
            }

            // 创建和替换报告内容
            try (InputStream is = new FileInputStream(templatePath);
                 XWPFDocument doc = new XWPFDocument(is)) {

                // 替换段落
                for (XWPFParagraph paragraph : doc.getParagraphs()) {
                    replaceInParagraph(paragraph, textReplaceMap);
                }

                // 替换表格
                for (XWPFTable table : doc.getTables()) {
                    for (XWPFTableRow row : table.getRows()) {
                        for (XWPFTableCell cell : row.getTableCells()) {
                            for (XWPFParagraph paragraph : cell.getParagraphs()) {
                                replaceInParagraph(paragraph, textReplaceMap);
                            }
                        }
                    }

                    // 填充表格内容，自动填充多行
                    fillTableData(table, makeReportDTO.getExcelData());
                }

                long timestamp = System.currentTimeMillis();
                int randomNum = new Random().nextInt(10000);
                String fileName = timestamp + "_" + randomNum + ".docx";
                String outPath = directoryPath + fileName;

                // 输出到文件
                try (OutputStream os = new FileOutputStream(outPath)) {
                    doc.write(os);
                }

                return AjaxResult.success(outPath);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("报告生成失败！");
        }
    }
*/


    /**
     * 目标性能预测报告
     * @param makeReportDTO
     * @return
     */
/*
    @PostMapping("make/report/target/performance/fifth")
    public AjaxResult makeTargetReportFifth (@RequestBody PerformanceFifthDTO makeReportDTO ) {

        String model = makeReportDTO.getModel();

        String target = makeReportDTO.getTarget();
        String number = makeReportDTO.getNumber();
        String detail = makeReportDTO.getDetail();
        String percentage = makeReportDTO.getPercentage();

        String r2 = makeReportDTO.getR2();
        String mse = makeReportDTO.getMse();
        String imageUrl = makeReportDTO.getImageUrl();



        // 文本占位符
        Map<String, String> textReplaceMap = new HashMap<>();
        // 获取当前日期
        LocalDateTime nowData = LocalDateTime.now();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        String dateStr = nowData.format(dateFormatter);
        textReplaceMap.put("${nowDate}", dateStr); // 当前日期替换
        textReplaceMap.put("${model}", model); // 当前日期替换
        textReplaceMap.put("${target}", target); // 当前日期替换
        textReplaceMap.put("${number}", number); // 当前日期替换
        textReplaceMap.put("${detail}", detail); // 当前日期替换
        textReplaceMap.put("${percentage}",percentage ); // 当前日期替换
        textReplaceMap.put("${r2}",r2 ); // 当前日期替换
        textReplaceMap.put("${mse}",mse ); // 当前日期替换

        textReplaceMap.put("${imageUrl}",imageUrl ); // 当前日期替换




        // 填充其他数据
        List<List<String>> excelData = makeReportDTO.getExcelData();
        textReplaceMap.put("${1}", excelData.get(0).get(0)); // 示例：水的数值替换
        textReplaceMap.put("${2}", excelData.get(0).get(1)); // 水泥PⅡ 52.5R
        textReplaceMap.put("${3}", excelData.get(0).get(2)); // 机制砂
        textReplaceMap.put("${5}", excelData.get(0).get(4)); // 碎石
        textReplaceMap.put("${6}", excelData.get(0).get(5)); // 矿渣粉
        textReplaceMap.put("${7}", excelData.get(0).get(6)); // 粉煤灰
        textReplaceMap.put("${8}", excelData.get(0).get(7)); // 减水剂
        textReplaceMap.put("${9}", excelData.get(0).get(8)); // 增效剂
        textReplaceMap.put("${10}", excelData.get(0).get(9)); // 3天抗压强度
        textReplaceMap.put("${11}", excelData.get(0).get(10)); // 7天抗压强度
        textReplaceMap.put("${12}", excelData.get(0).get(11)); // 28天抗压强度

        // Excel 文件路径和模板路径
        String templatePath = uploadPklExcelPath + "template5.docx";
        String directoryPath = fileUploadDir;

        try {
            // 检查目录并创建目录
            if (!Files.exists(Paths.get(directoryPath))) {
                Files.createDirectories(Paths.get(directoryPath));
            }

            // 创建和替换报告内容
            try (InputStream is = new FileInputStream(templatePath);
                 XWPFDocument doc = new XWPFDocument(is)) {

                // 替换段落
                for (XWPFParagraph paragraph : doc.getParagraphs()) {
                    replaceInParagraph(paragraph, textReplaceMap);
                }

                // 替换表格
                for (XWPFTable table : doc.getTables()) {
                    for (XWPFTableRow row : table.getRows()) {
                        for (XWPFTableCell cell : row.getTableCells()) {
                            for (XWPFParagraph paragraph : cell.getParagraphs()) {
                                replaceInParagraph(paragraph, textReplaceMap);
                            }
                        }
                    }

                    // 填充表格内容，自动填充多行
                    fillTableData(table, makeReportDTO.getExcelData());
                }

                long timestamp = System.currentTimeMillis();
                int randomNum = new Random().nextInt(10000);
                String fileName = timestamp + "_" + randomNum + ".docx";
                String outPath = directoryPath + fileName;

                // 输出到文件
                try (OutputStream os = new FileOutputStream(outPath)) {
                    doc.write(os);
                }

                return AjaxResult.success(outPath);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("报告生成失败！");
        }
    }

*/


    /**
     * 替换段落中的占位符
     */
//    private void replaceInParagraph(XWPFParagraph paragraph, Map<String, String> textReplaceMap) {
//        List<XWPFRun> runs = paragraph.getRuns();
//        if (runs == null || runs.isEmpty()) {
//            return;
//        }
//
//        StringBuilder fullText = new StringBuilder();
//        List<Integer> textRunIndexes = new ArrayList<>();
//
//        // 拼接完整文本并记录含文字的 run 索引
//        for (int i = 0; i < runs.size(); i++) {
//            String text = runs.get(i).getText(0);
//            if (text != null) {
//                fullText.append(text);
//                textRunIndexes.add(i);
//            }
//        }
//
//        // 执行文本替换
//        String replacedText = fullText.toString();
//        for (Map.Entry<String, String> entry : textReplaceMap.entrySet()) {
//            replacedText = replacedText.replace(entry.getKey(), entry.getValue());
//        }
//
//        // 将替换后的文本，按原 run 数量写回（简单处理为一个 run）
//        if (!textRunIndexes.isEmpty()) {
//            // 清空原文字 runs 的文本内容
//            for (int idx : textRunIndexes) {
//                runs.get(idx).setText("", 0);
//            }
//
//            // 仅在第一个文字 run 写入新文本，其它 run 保留（包括含图 run）
//            runs.get(textRunIndexes.get(0)).setText(replacedText, 0);
//        }
//    }

    /**
     * 替换段落中的占位符
     */
    private void replaceInParagraph(XWPFParagraph paragraph, Map<String, String> textReplaceMap) {
        // 原有代码不变
        List<XWPFRun> runs = paragraph.getRuns();
        if (runs == null || runs.isEmpty()) {
            return;
        }

        StringBuilder fullText = new StringBuilder();
        List<Integer> textRunIndexes = new ArrayList<>();

        // 拼接完整文本并记录含文字的 run 索引
        for (int i = 0; i < runs.size(); i++) {
            String text = runs.get(i).getText(0);
            if (text != null) {
                fullText.append(text);
                textRunIndexes.add(i);
            }
        }

        // 执行文本替换
        String replacedText = fullText.toString();
        for (Map.Entry<String, String> entry : textReplaceMap.entrySet()) {
            replacedText = replacedText.replace(entry.getKey(), entry.getValue());
        }

        // 将替换后的文本，按原 run 数量写回（简单处理为一个 run）
        if (!textRunIndexes.isEmpty()) {
            // 清空原文字 runs 的文本内容
            for (int idx : textRunIndexes) {
                runs.get(idx).setText("", 0);
            }

            // 仅在第一个文字 run 写入新文本，其它 run 保留（包括含图 run）
            runs.get(textRunIndexes.get(0)).setText(replacedText, 0);
        }
    }

    /**
     * 填充表格内容，自动填充多行，保留格式（特别是列宽和样式）且第一行不变，处理单组数据
     */
    private void fillTableData(XWPFTable table, List<List<String>> excelData) {
        if (excelData == null || excelData.isEmpty()) {
            return;
        }
        if (table.getNumberOfRows() < 2) {
            return;
        }

        XWPFTableRow templateRow = table.getRow(1); // 第2行是模板

        // 删除多余行，仅保留表头和模板行
        while (table.getNumberOfRows() > 2) {
            table.removeRow(2);
        }

        // 插入所有数据行
        for (int i = 0; i < excelData.size(); i++) {
            List<String> rowData = excelData.get(i);

            // 插入新行
            XWPFTableRow newRow = table.insertNewTableRow(i + 1);
            for (int colIndex = 0; colIndex < templateRow.getTableCells().size(); colIndex++) {
                XWPFTableCell templateCell = templateRow.getCell(colIndex);
                XWPFTableCell newCell = newRow.addNewTableCell();

                // 复制样式
                newCell.getCTTc().setTcPr(templateCell.getCTTc().getTcPr());
                XWPFParagraph newParagraph = newCell.getParagraphs().get(0);
                newParagraph.getCTP().setPPr(templateCell.getParagraphs().get(0).getCTP().getPPr());

                // 设置内容
                XWPFRun run = newParagraph.createRun();
                if (colIndex < rowData.size()) {
                    run.setText(rowData.get(colIndex));
                }

                // 复制字体样式
                List<XWPFRun> templateRuns = templateCell.getParagraphs().get(0).getRuns();
                if (!templateRuns.isEmpty()) {
                    run.getCTR().setRPr(templateRuns.get(0).getCTR().getRPr());
                }
            }
        }

        // 删除模板行
        table.removeRow(1);
    }

/*
    private void fillTableData(XWPFTable table, List<List<String>> excelData) {
        if (excelData == null || excelData.isEmpty()) {
            return;
        }
        if (table.getNumberOfRows() < 2) {
            return;
        }

        XWPFTableRow templateRow = table.getRow(1);

        // 删除多余数据行，仅保留表头和模板行
        while (table.getNumberOfRows() > 2) {
            table.removeRow(2);
        }

        for (int i = 0; i < excelData.size(); i++) {
            List<String> rowData = excelData.get(i);

            XWPFTableRow newRow;
            if (i == 0) {
                // 使用模板行
                newRow = templateRow;
            } else {
                // 插入新行
                newRow = table.insertNewTableRow(i + 1);
                for (int colIndex = 0; colIndex < templateRow.getTableCells().size(); colIndex++) {
                    XWPFTableCell templateCell = templateRow.getCell(colIndex);
                    XWPFTableCell newCell = newRow.addNewTableCell();
                    newCell.getCTTc().setTcPr(templateCell.getCTTc().getTcPr());
                    newCell.getParagraphs().get(0).getCTP().setPPr(templateCell.getParagraphs().get(0).getCTP().getPPr());
                }
            }

            for (int colIndex = 0; colIndex < newRow.getTableCells().size(); colIndex++) {
                XWPFTableCell cell = newRow.getCell(colIndex);
                XWPFParagraph paragraph = cell.getParagraphs().get(0);

                // 清空原有内容
                for (int r = paragraph.getRuns().size() - 1; r >= 0; r--) {
                    paragraph.removeRun(r);
                }

                XWPFRun run = paragraph.createRun();
                if (colIndex < rowData.size()) {
                    run.setText(rowData.get(colIndex));
                }

                // 复制样式
                List<XWPFRun> templateRuns = templateRow.getCell(colIndex).getParagraphs().get(0).getRuns();
                if (!templateRuns.isEmpty()) {
                    run.getCTR().setRPr(templateRuns.get(0).getCTR().getRPr());
                }
            }
        }

        // 删除模板行（第2行）
        table.removeRow(1);
    }
*/

/*
    private void fillTableData(XWPFTable table, List<List<String>> excelData) {
        if (excelData == null || excelData.isEmpty()) {
            return;
        }
        if (table.getNumberOfRows() < 2) {
            // 没有示例行，仅表头，无法复制格式
            return;
        }
        XWPFTableRow templateRow = table.getRow(1); // 假设第1行为示例样式行

        // 删除多余的模板行（除了表头和示例行）
        while (table.getNumberOfRows() > 2) {
            table.removeRow(2);
        }

        if (excelData.size() == 1) {
            // 只有一组数据，直接填充到第二行
            List<String> rowData = excelData.get(0);
            XWPFTableRow targetRow = table.getRow(1);
            for (int colIndex = 0; colIndex < targetRow.getTableCells().size(); colIndex++) {
                XWPFTableCell cell = targetRow.getCell(colIndex);
                XWPFParagraph paragraph = cell.getParagraphs().get(0);
                XWPFRun run = paragraph.createRun();
                if (colIndex < rowData.size()) {
                    run.setText(rowData.get(colIndex));
                }
                // 复制字体样式
                List<XWPFRun> templateRuns = templateRow.getCell(colIndex).getParagraphs().get(0).getRuns();
                if (!templateRuns.isEmpty()) {
                    run.getCTR().setRPr(templateRuns.get(0).getCTR().getRPr());
                }
            }
        } else {
            // 多组数据，按原逻辑处理
            for (int rowIndex = 1; rowIndex < excelData.size(); rowIndex++) {
                List<String> rowData = excelData.get(rowIndex);

                // 复制示例行
                XWPFTableRow newRow = table.insertNewTableRow(rowIndex + 1);
                for (int colIndex = 0; colIndex < templateRow.getTableCells().size(); colIndex++) {
                    XWPFTableCell templateCell = templateRow.getCell(colIndex);
                    XWPFTableCell newCell = newRow.addNewTableCell();

                    // 复制段落格式
                    newCell.getCTTc().setTcPr(templateCell.getCTTc().getTcPr());

                    // 设置内容
                    XWPFParagraph newParagraph = newCell.getParagraphs().get(0);
                    newParagraph.getCTP().setPPr(templateCell.getParagraphs().get(0).getCTP().getPPr());

                    XWPFRun run = newParagraph.createRun();
                    if (colIndex < rowData.size()) {
                        run.setText(rowData.get(colIndex));
                    }

                    // 复制字体样式
                    List<XWPFRun> templateRuns = templateCell.getParagraphs().get(0).getRuns();
                    if (!templateRuns.isEmpty()) {
                        run.getCTR().setRPr(templateRuns.get(0).getCTR().getRPr());
                    }
                }
            }
        }

        // 删除模板中原有的示例行
        table.removeRow(1);
    }
*/


//    private void replaceInParagraph(XWPFParagraph paragraph, Map<String, String> textReplaceMap) {
//        StringBuilder fullText = new StringBuilder();
//        List<XWPFRun> runs = paragraph.getRuns();
//
//        // 拼接完整文本
//        for (XWPFRun run : runs) {
//            if (run.getText(0) != null) {
//                fullText.append(run.getText(0));
//            }
//        }
//
//        String replacedText = fullText.toString();
//
//        // 替换文字
//        for (Map.Entry<String, String> entry : textReplaceMap.entrySet()) {
//            replacedText = replacedText.replace(entry.getKey(), entry.getValue());
//        }
//
//        // 清空原 runs
//        for (int i = runs.size() - 1; i >= 0; i--) {
//            paragraph.removeRun(i);
//        }
//
//        // 写入新的文本 run
//        if (!replacedText.isEmpty()) {
//            XWPFRun newRun = paragraph.createRun();
//            newRun.setText(replacedText);
//        }
//    }

    /**
     * 填充表格内容，自动填充多行，保留格式（特别是列宽和样式）且第一行不变
     */
//    private void fillTableData(XWPFTable table, List<List<String>> excelData) {
//        if (table.getNumberOfRows() < 2) {
//            // 没有示例行，仅表头，无法复制格式
//            return;
//        }
//
//        XWPFTableRow templateRow = table.getRow(1); // 假设第1行为示例样式行
//
//        // 删除多余的模板行（除了表头和示例行）
//        while (table.getNumberOfRows() > 2) {
//            table.removeRow(2);
//        }
//
//        for (int rowIndex = 1; rowIndex < excelData.size(); rowIndex++) {
//            List<String> rowData = excelData.get(rowIndex);
//
//            // 复制示例行
//            XWPFTableRow newRow = table.insertNewTableRow(rowIndex + 1);
//            for (int colIndex = 0; colIndex < templateRow.getTableCells().size(); colIndex++) {
//                XWPFTableCell templateCell = templateRow.getCell(colIndex);
//                XWPFTableCell newCell = newRow.addNewTableCell();
//
//                // 复制段落格式
//                newCell.getCTTc().setTcPr(templateCell.getCTTc().getTcPr());
//
//                // 设置内容
//                XWPFParagraph newParagraph = newCell.getParagraphs().get(0);
//                newParagraph.getCTP().setPPr(templateCell.getParagraphs().get(0).getCTP().getPPr());
//
//                XWPFRun run = newParagraph.createRun();
//                if (colIndex < rowData.size()) {
//                    run.setText(rowData.get(colIndex));
//                }
//
//                // 复制字体样式
//                List<XWPFRun> templateRuns = templateCell.getParagraphs().get(0).getRuns();
//                if (!templateRuns.isEmpty()) {
//                    run.getCTR().setRPr(templateRuns.get(0).getCTR().getRPr());
//                }
//            }
//        }
//
//        // 删除模板中原有的示例行
//        table.removeRow(1);
//    }









/*
    @PostMapping("make/report/target/performance/fifth")
    public AjaxResult makeTargetReportFifth(@RequestBody PerformanceFifthDTO makeReportDTO) {

        String model = makeReportDTO.getModel();
        String target = makeReportDTO.getTarget();
        String number = makeReportDTO.getNumber();
        String detail = makeReportDTO.getDetail();
        String percentage = makeReportDTO.getPercentage();
        String r2 = makeReportDTO.getR2();
        String mse = makeReportDTO.getMse();
        String imageUrl = makeReportDTO.getImageUrl();

        // 文本占位符
        Map<String, String> textReplaceMap = new HashMap<>();
        LocalDateTime nowData = LocalDateTime.now();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        String dateStr = nowData.format(dateFormatter);
        textReplaceMap.put("${nowDate}", dateStr);
        textReplaceMap.put("${model}", model);
        textReplaceMap.put("${target}", target);
        textReplaceMap.put("${number}", number);
        textReplaceMap.put("${detail}", detail);
        textReplaceMap.put("${percentage}", percentage);
        textReplaceMap.put("${r2}", r2);
        textReplaceMap.put("${mse}", mse);

        // 图片占位符（图像路径需为本地路径或转换为 InputStream）
        Map<String, String> imageReplaceMap = new HashMap<>();
        imageReplaceMap.put("${imageUrl}", imageUrl); // Word 模板中 ${imageUrl} 将被替换为图片

        // Excel数据替换
        List<List<String>> excelData = makeReportDTO.getExcelData();
        if (excelData != null && !excelData.isEmpty()) {
            List<String> row = excelData.get(0);
            textReplaceMap.put("${1}", row.get(0));
            textReplaceMap.put("${2}", row.get(1));
            textReplaceMap.put("${3}", row.get(2));
            textReplaceMap.put("${5}", row.get(4));
            textReplaceMap.put("${6}", row.get(5));
            textReplaceMap.put("${7}", row.get(6));
            textReplaceMap.put("${8}", row.get(7));
            textReplaceMap.put("${9}", row.get(8));
            textReplaceMap.put("${10}", row.get(9));
            textReplaceMap.put("${11}", row.get(10));
            textReplaceMap.put("${12}", row.get(11));
        }

        // 模板路径和输出目录
        String templatePath = uploadPklExcelPath + "template5.docx";
        String directoryPath = fileUploadDir;

        try {
            if (!Files.exists(Paths.get(directoryPath))) {
                Files.createDirectories(Paths.get(directoryPath));
            }

            try (InputStream is = new FileInputStream(templatePath);
                 XWPFDocument doc = new XWPFDocument(is)) {

                // 替换段落中的文字和图片
                for (XWPFParagraph paragraph : doc.getParagraphs()) {
                    replaceInParagraphV2(paragraph, textReplaceMap, imageReplaceMap); // 替换图片+文本
                }

                // 替换表格
                for (XWPFTable table : doc.getTables()) {
                    for (XWPFTableRow row : table.getRows()) {
                        for (XWPFTableCell cell : row.getTableCells()) {
                            for (XWPFParagraph paragraph : cell.getParagraphs()) {
                                replaceInParagraphV2(paragraph, textReplaceMap, imageReplaceMap);
                            }
                        }
                    }

                    // 填充表格数据
                    fillTableData(table, makeReportDTO.getExcelData());
                }

                // 输出报告
                long timestamp = System.currentTimeMillis();
                int randomNum = new Random().nextInt(10000);
                String fileName = timestamp + "_" + randomNum + ".docx";
                String outPath = directoryPath + fileName;

                try (OutputStream os = new FileOutputStream(outPath)) {
                    doc.write(os);
                }

                return AjaxResult.success(outPath);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("报告生成失败！");
        }
    }


    private void replaceInParagraphV2(XWPFParagraph paragraph, Map<String, String> textReplaceMap, Map<String, String> imageReplaceMap) {
        for (XWPFRun run : paragraph.getRuns()) {
            String text = run.getText(0);
            if (text != null) {
                for (Map.Entry<String, String> entry : textReplaceMap.entrySet()) {
                    if (text.contains(entry.getKey())) {
                        text = text.replace(entry.getKey(), entry.getValue());
                        run.setText(text, 0);
                    }
                }

                for (Map.Entry<String, String> entry : imageReplaceMap.entrySet()) {
                    if (text.contains(entry.getKey())) {
                        text = text.replace(entry.getKey(), ""); // 清除文本占位符
                        run.setText(text, 0);

                        try (InputStream imageStream = new FileInputStream(entry.getValue())) {
                            run.addPicture(imageStream, Document.PICTURE_TYPE_PNG, entry.getValue(), Units.toEMU(400), Units.toEMU(300)); // 控制图片大小
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

*/


}